package org.go.server;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.go.expcetion.GoException;
import org.go.scheduler.Scheduler;
import org.go.scheduler.SchedulerFactory;
import org.go.scheduler.StdSchedulerFactory;

/**
 * <p>
 * Instantiates an instance of Go Scheduler as a stand-alone program, if
 * the scheduler is configured for RMI it will be made available.
 * </p>
 *
 * <p>
 * The main() method of this class currently accepts 0 or 1 arguemtns, if there
 * is an argument, and its value is <code>"console"</code>, then the program
 * will print a short message on the console (std-out) and wait for the user to
 * type "exit" - at which time the scheduler will be shutdown.
 * </p>
 *
 * <p>
 * Future versions of this server should allow additional configuration for
 * responding to scheduler events by allowing the user to specify <code>{@link org.go.listener.WorkListener}</code>,
 * <code>{@link org.go.TriggerListener}</code> and <code>{@link org.go.listener.SchedulerListener}</code>
 * classes.
 * </p>
 *
 * <p>
 * Please read the Go FAQ entries about RMI before asking questions in the
 * forums or mail-lists.
 * </p>
 *
 * @author hejie
 */
public class GoServer {

	public static void main(String[] args) throws Exception {
		if (System.getSecurityManager() == null) {
			System.setSecurityManager(new java.rmi.RMISecurityManager());
		}
		try {
			GoServer server = new GoServer();
			if (args.length == 0) {
				server.serve(new StdSchedulerFactory(), false);
			} else if (args.length == 1 && args[0].equalsIgnoreCase("console")) {
				server.serve(new StdSchedulerFactory(), true);
			} else {
				System.err.println("\nUsage: GoServer [console]");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private Scheduler sched = null;

	public GoServer() {
	}

	/**
	 * <p>
	 * Called by the <code>{@link Scheduler}</code> when a serious error has
	 * occured within the scheduler - such as repeated failures in the <code>JobStore</code>,
	 * or the inability to instantiate a <code>Job</code> instance when its
	 * <code>Trigger</code> has fired.
	 * </p>
	 *
	 * <p>
	 * The <code>getErrorCode()</code> method of the given SchedulerException
	 * can be used to determine more specific information about the type of
	 * error that was encountered.
	 * </p>
	 */
	public void schedulerError(String msg, GoException cause) {
		System.err.println("*** " + msg);
		cause.printStackTrace();
	}

	/**
	 * <p>
	 * Called by the <code>{@link Scheduler}</code> to inform the listener
	 * that it has shutdown.
	 * </p>
	 */
	public void schedulerShutdown() {
		System.out.println("\n*** The scheduler is now shutdown.");
		sched = null;
	}

	public void serve(SchedulerFactory schedFact, boolean console) throws Exception {
		sched = schedFact.getScheduler("DefaultQuartzScheduler1");
		//sched.startAll();
		try {
			Thread.sleep(3000l);
		} catch (Exception ignore) {
		}

		System.out.println("\n*** The scheduler successfully started.");

		if (console) {
			System.out.println("\n");
			System.out.println("The scheduler will now run until you type \"exit\"");
			System.out.println("   If it was configured to export itself via RMI,");
			System.out.println("   then other process may now use it.");

			BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));

			while (true) {
				System.out.print("Type 'exit' to shutdown the server: ");
				if ("exit".equals(rdr.readLine())) {
					break;
				}
			}
			System.out.println("\n...Shutting down server...");
			sched.shutdown(true);
		}
	}
}
